package Q15_04_Deadlock_Free_Class; import java.util.ArrayList; import java.util.HashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockNode { public enum VisitState { FRESH, VISITING, VISITED }; private ArrayList<LockNode> children; private int lockId; private Lock lock; private int maxLocks; public LockNode(int id, int max) { lockId = id; children = new ArrayList<LockNode>(); maxLocks = max; } /* Join "this" to "node", checking to make sure that it doesn't create a cycle */ public void joinTo(LockNode node) { children.add(node); } public void remove(LockNode node) { children.remove(node); } /* Check for a cycle by doing a depth-first-search. */ public boolean hasCycle(HashMap<Integer, Boolean> touchedNodes) { VisitState[] visited = new VisitState[maxLocks]; for (int i = 0; i < maxLocks; i++) { visited[i] = VisitState.FRESH; } return hasCycle(visited, touchedNodes); } private boolean hasCycle(VisitState[] visited, HashMap<Integer, Boolean> touchedNodes) { if (touchedNodes.containsKey(lockId)) { touchedNodes.put(lockId, true); } if (visited[lockId] == VisitState.VISITING) { return true; } else if (visited[lockId] == VisitState.FRESH) { visited[lockId] = VisitState.VISITING; for (LockNode n : children) { if (n.hasCycle(visited, touchedNodes)) { return true; } } visited[lockId] = VisitState.VISITED; } return false; } public Lock getLock() { if (lock == null) { lock = new ReentrantLock(); } return lock; } public int getId() { return lockId; } }